<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>{% block title %}{{ application_name }}{% endblock %}</title>
    <style type="text/css">
      .good {background-color: white;}
      .bad  {background-color: red;}
      input {text-align: right; font-size:20px; width:150px}
      .mean {font-weight:bold;}
      .mean td {background-color:#F0F8FF;}
      .mean td input {background-color:#F0F8FF;border:none;}
    </style>
    <script type="text/javascript">

      function id_from_location(location){
        return "EXPERIMENTS["+location.experiment+"].observations["+location.observation+"].replicates["+location.replicate+"].data["+location.data+"]";
      }
      
      function indexOf(array, obj){
        for(var i=0; i<array.length; i++){
          if(array[i]==obj){
            return i;
          }
        }
        return -1;
      }
      function update_experiment_data_with_value(id, value){
        var l = data_location(id);
        EXPERIMENTS[l.experiment].observations[l.observation].replicates[l.replicate].data[l.data] = Number(value);
      }
      
      function data_location(id){
        var r = /EXPERIMENTS\[(\d*)\]\.observations\[(\d*)\]\.replicates\[(\d*)\]\.data\[(\d*)\]/;
        var results = id.match(r);

        var location = {}
        if (null != results){
          location.experiment = Number(results[1]);
          location.observation = Number(results[2]);
          location.replicate = Number(results[3]);
          location.data = Number(results[4]);
        }

        return location;
      }
//#########
// Selects the next input data element in the direction from the passed input element
function selectDataFrom(input,direction){
  var location = data_location(input.id);

  // Change style on current input to be not_selected
  //input.setAttribute('class','not_selected_input');

  switch(direction){
    case 38: // Up
      location_up_from(location);
      break;
    case 40: // Down
      location_down_from(location);
      break;
    case 37: // Left
      // Cursor Caret is at the beginning, move to the next cell on the left
      //if (input.selectionStart == 0)
      location_left_from(location);
      break;
    case 39: // Right
      // Cursor Caret is at the end; move to the next cell on the right
      //if (input.selectionStart == input.value.length)
      location_right_from(location);
      break;
  }

  var element = document.getElementById(id_from_location(location));
  //element.setAttribute('class','selected_input');
  element.select();
   
  function location_up_from(location){
    // Are we on the first replicate of the observation?
    if (0 == location.replicate){
      // Are we on the first observation of the experiment?
      if (0 == location.observation){
         // Do nothing... at the begining  
      }
      else{
        location.observation -= 1;
        location.replicate = EXPERIMENTS[location.experiment].observations[location.observation].replicates.length - 1;
      }
    }
    else{
      location.replicate -= 1;
    }
  }

  function location_down_from(location){
    // Are we on the last replicate of the observation?
    if (EXPERIMENTS[location.experiment].observations[location.observation].replicates.length - 1 == location.replicate){
      // Are we on the last observation of the experiment?
      if (EXPERIMENTS[location.experiment].observations.length -1 == location.observation){
        // Do nothing... at the end
      }
      else{
        location.observation += 1;
        location.replicate = 0;
      }
    }
    else{
      location.replicate += 1;
    }
  }

  function location_left_from(location){
    // Are we on the first data column of the replicate?
    if (0 == location.data){
     // Do nothing... at the begining  
    }
    else{
      location.data -= 1;
    }
  }

  function location_right_from(location){
    // Are we on the first data column of the replicate?
    if (EXPERIMENTS[location.experiment].observations[location.observation].replicates[location.replicate].data.length - 1 == location.data){
     // Do nothing... at the end  
    }
    else{
      location.data += 1;
    }
  }
} 



//########### 
      function isNumberDecimalKey(evt){
        // Keep track of orginal value in case the ESC key is pressed.
        if (evt.target.old_value == null)
        {
          evt.target.old_value = evt.target.value
        }
       
        var charCode = (evt.which) ? evt.which : evt.keyCode
         
        // If ESC is pressed return to the old value
        if (charCode == 27){
          evt.target.value = evt.target.old_value;
          evt.target.old_value = null;
          evt.target.blur();
          evt.target.select();
          evt.stopPropagation();
          return false;
        }
         
        // if command, control, or alt key was pressed
        if (evt.metaKey || evt.ctrlKey || evt.altKey){
          return true;
        }
           
        // If period was pressed
        if (charCode == 190){
          return true;
        }
      
        // If minus was pressed
        if (charCode == 109){
          return true;
        }
        
        // If an arrow key was pressed
        if (charCode >= 37 && charCode <= 40){
          selectDataFrom(evt.target, charCode);
          evt.stopPropagation();
          return false;
        }
      
        if (charCode != 46 && charCode > 31 && (charCode < 48 || charCode > 57))
          return false;

        return true;
         
      }
      
      function formatNumberFor(input){
        var number = Number(input.value).toFixed(9);
        input.value = number;
        update_experiment_data_with_value(input.id, number);        
        update_means_for(input.id);
      }
      
      function update_means_for(id)
      {
        var r = /EXPERIMENTS\[(\d*)\]\.observations\[(\d*)\]\.replicates\[(\d*)\]\.data\[(\d*)\]/;
        var results = id.match(r);
        var experiment_number = null;
        var observation_number = null;
        
        if (null != results){
          experiment_number = results[1];
          observation_number = results[2];
        }
        var data_column = null;
        
        if (null != results){
          data_column = results[4];
        }
        var replicates = EXPERIMENTS[experiment_number].observations[observation_number].replicates;
        
        var sum = null;
        var mean = null;
        // Add up sum of observations
        for (var r in replicates){
          var replicate = replicates[r]
          if (sum == null)
            sum = replicate.data[data_column];
          else{
            var value = replicate.data[data_column];
            if ((value == NaN) || (sum == NaN))
              sum = NaN;
            else
              sum += value;
          }
        }
        
        if (sum != NaN)
          mean = Number(sum/replicates.length).toFixed(9);  
        
        var mean_input = document.getElementById(id.split("replicates")[0]+"mean["+data_column+"]");
        mean_input.value = mean; 
      }
      
      function set_display_style_for_data_rows_for_experiment(experiment_number, style){
        var experiment = EXPERIMENTS[experiment_number];
        for(var o in experiment.observations){
          var observation = experiment.observations[o];
          for(var r in observation.replicates){
            var element_id = 'EXPERIMENTS['+experiment_number+'].observations['+o+'].replicates['+r+']';
            var e = document.getElementById(element_id);
            e.style.display = style;
          }
        }
      }
      
      function show_all(experiment_number){
        set_display_style_for_data_rows_for_experiment(experiment_number, "");
        
        var show_all_div = document.getElementById("show_all_"+experiment_number);
        show_all_div.style.display = "none";
        var show_means_div = document.getElementById("show_means_"+experiment_number);
        show_means_div.style.display = "";
        
        // Select first data element in that experiment
        var element = document.getElementById('EXPERIMENTS['+experiment_number+'].observations[0].replicates[0].data[0]');
        element.focus();
        element.select();
      }

      function show_means(experiment_number){
        set_display_style_for_data_rows_for_experiment(experiment_number, "none");
        
        var show_all_div = document.getElementById("show_all_"+experiment_number);
        show_all_div.style.display = "";
        var show_means_div = document.getElementById("show_means_"+experiment_number);
        show_means_div.style.display = "none";    
      }

      function populate(){
        var experiments_div = document.getElementById('experiments');
        if (experiments_div)
          alert('found it');
        else{
          //alert('not found');
          create_experiments_div();
        }

      }
      
      function set_attributes(attributes, element){
        // keywords that need to be defined on the attribute
        
        // Add Attributes
        if(attributes != undefined){
          for (var i in attributes){
            if (i == 'readOnly'){
              element[i] = attributes[i];
            }
            else
              element.setAttribute(i,attributes[i]);
          }
        }
        
      }

      function create_element(element_name, attributes, value){
        var element = document.createElement(element_name);

        if (attributes)
         set_attributes(attributes, element);

        // Add TextNode value
        if(value != undefined){
          element.appendChild(document.createTextNode(value));
        }

        return element;
      }

      function create_table_header(name){
        var th = create_element('th');
        th.appendChild(document.createTextNode(name))
        return th;  
      }

      function create_table_data(value){
        var td = create_element('td');
        td.innerHTML = value;
        return td;
      }

      function add_headers_to_table_row(header_names, row){
        for (var i in header_names){
          var th = create_table_header(header_names[i]);
          row.appendChild(th);
        }  
      }
      
      function add_table_data_input_field_to_row(value, row, attributes){
        var td = create_element('td');
        
        var input = create_element('input',{'type':'text'})
        if(attributes)
          set_attributes(attributes, input);
        // Check for NaN
        if (!isNaN(value))
          input.setAttribute('value',Number(value).toFixed(9));
        td.appendChild(input);
        
        row.appendChild(td);
      }
      
      // Take an array of data and add it to the row
      function add_data_to_table_row(data, row, attributes){
        for (var i in data){
          add_table_data_input_field_to_row(data[i], row, attributes);
        }
      }

      function create_experiments_div(){
        var div = create_element('div',{'id': 'experiments'});
        document.body.appendChild(div);
        
        for (var i in EXPERIMENTS){
          add_experiment_to_div(EXPERIMENTS[i], div, i);
        }
        
        // Select first data row in Experiment 1
        var cell = "EXPERIMENTS[0].observations[0].replicates[0].data[0]"
        document.getElementById(cell).select();
        
        function add_experiment_to_div(experiment, div, experiment_number){
          var experiment_id = "EXPERIMENTS["+i+"]"
          
          // Add Experiment Description
          div.appendChild(create_element('h2',{},experiment.description));
          // Add Data/Means Filter
          add_data_means_filter(experiment_number, div);
          
          var table = create_element('table');
          
          // Add Experiment Header
          add_experiment_header_to_table(experiment.header, table);
          // Add Experiment Observations
          add_experiment_observations_to_table(experiment.observations, table, experiment_id);
          
          div.appendChild(table);
          
          function add_data_means_filter(experiment_number, div){
            var show_all_div = create_element('div', {'id':'show_all_'+experiment_number});
            var show_all_link = create_element('a',{'href':'javascript:show_all('+experiment_number+')'}, 'Show all data');
            show_all_div.appendChild(show_all_link);
            var show_means_div = create_element('div', {'id':'show_means_'+experiment_number, 'style':'display:none;'});
            var show_means_link = create_element('a',{'href':'javascript:show_means('+experiment_number+')'}, 'Show only means');
            show_means_div.appendChild(show_means_link);
            div.appendChild(show_all_div);
            div.appendChild(show_means_div);
          }
          
          function add_experiment_header_to_table(header, table){
            var tr = create_element('tr');
            table.appendChild(tr);

            // Add Input Headers to Header Row
            //add_headers_to_table_row(header.input_header, tr);
            // Add Time Header
            tr.appendChild(create_table_header(header.time_header));
            // Add Replicate Header
            tr.appendChild(create_table_header(header.replicate_header));
            // Add Observation Header
            add_headers_to_table_row(header.observation_header, tr);            
          }

          function add_experiment_observations_to_table(observations, table, experiment_id){
            for (var i in observations){
              var observation_id = experiment_id + ".observations[" + i +"]";
              add_experiment_observation_to_table(observations[i], table, observation_id, experiment_id);
            }

            function add_experiment_observation_to_table(observation, table, observation_id, experiment_id){
              for (var i in observation.replicates){
                var replicate_id = observation_id + ".replicates[" + i + "]";
                var tr = create_element('tr',{'class':'data',
                                              'name':experiment_id,
                                              'style':'display:none',
                                              'id':replicate_id});
                var replicate = observation.replicates[i];
                // Add Time
                tr.appendChild(create_table_data(observation.time));
                // Add Replicate Data
                add_replicate_data_to_row(replicate, tr, replicate_id);
                
                table.appendChild(tr);
              }
              add_means_for_observation_to_table(observation, table, observation_id);

              function add_means_for_observation_to_table(observation, table, observation_id){
                var tr = create_element('tr',{'class':'mean'});
                // Mean Observation Time
                tr.appendChild(create_table_data(observation.time));
                // Mean Description 
                tr.appendChild(create_table_data("Mean"));
                // Add means
                var means =  means_for_observation(observation);
                for (var i in means){
                  var attributes = {'class':'mean',
                                    'readOnly':true, 
                                    'id':observation_id + ".mean["+i+"]",
                                    'onclick':'return false;'};
                  add_table_data_input_field_to_row(means[i], tr, attributes);
                }
                table.appendChild(tr);
              }

              function add_replicate_data_to_row(replicate, row, replicate_id){
                row.appendChild(create_table_data(replicate.number));
                for (var i in replicate.data){
                  var attributes = {"onkeydown":"return isNumberDecimalKey(event)", 
                                    "onchange":"formatNumberFor(this)", 
                                    "onblur":"this.old_value=null",
                                    "onclick": "this.select()",
                                    "id":replicate_id+".data["+ i + "]"};
                  add_table_data_input_field_to_row(replicate.data[i], row, attributes);
                }
              }

              function means_for_observation(observation){
                var means = [];

                // Add up sum of observations
                for (var r in observation.replicates){
                  var replicate = observation.replicates[r]
                  for (var index in replicate.data){
                    var value = replicate.data[index];
                    if (undefined == means[index])
                      means[index] = value;
                    else if ((value == NaN) || (means[index] == NaN))
                      means[index] = NaN;
                    else
                      means[index] += value;
                  }
                }
                
                // Divide by number of replicates
                for (var i in means){
                  if (means[i] != NaN)
                    means[i] = Number(means[i]/observation.replicates.length).toFixed(9);
                }

                return means;
              }
            }
          }
        }  
      }
    
    // Kludge to get around longer rendering times with FireFox
    var alreadyrunflag=0 //flag to indicate whether target function has already been run

    if (document.addEventListener)
      document.addEventListener("DOMContentLoaded", function(){alreadyrunflag=1; populate();}, false)
    else if (document.all && !window.opera){
      document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>')
      var contentloadtag=document.getElementById("contentloadtag")
      contentloadtag.onreadystatechange=function(){
        if (this.readyState=="complete"){
          alreadyrunflag=1
          populate();
        }
      }
    }

    window.onload=function(){
      setTimeout("if (!alreadyrunflag){populate()}", 0)
    }
      
    </script>
    {% block head %}{% endblock %}
  </head>
  <body {% block onload %}{% endblock %}>
    <div id="body">{% block body %}{% endblock %}</div>
  </body>
</html>
